package com.sunday.framework.dubbo.autoconfiguration;

import com.sunday.common.core.constants.LogConstants;
import com.sunday.common.core.remoting.base.response.ExceptionResponse;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * @Description: Dubbo 日志输出
 * <p>
 * 请求参数验证 - 默认实现 :
 * 1. 请求日志/响应日志
 */
@Slf4j
@Configuration
@ConditionalOnProperty(prefix = "sunday.framework.dubbo", value = "execution")
public class DubboAdvisorAutoConfiguration {

    @Bean
    public Advisor dubboPointcutAdvisor(@Value("${sunday.framework.dubbo.execution}") String execution) {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(execution);
        return new DefaultPointcutAdvisor(pointcut, (MethodInterceptor) invocation -> {
            Method method = invocation.getMethod();
            try {
                /** 请求信息 日志打印 */
                log.info(LogConstants.request_format_aop,
                        Arrays.stream(invocation.getArguments()).map(String::valueOf).collect(Collectors.joining(",")),
                        method.getDeclaringClass(),
                        method.getName());
                /** 执行方法 */
                Object response = invocation.proceed();
                /** 响应信息 日志打印 */
                log.info(LogConstants.response_format_ack, response);
                return response;
            } catch (Throwable e) {
                /** 异常信息集中处理 */
                return ExceptionResponse.returnResponse(e);
            }
        });
    }
}
